/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.projectdarkstar.ai.tree;

import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.ManagedObject;
import com.sun.sgs.app.ManagedReference;
import com.sun.sgs.app.Task;
import java.io.Serializable;

/**
 *
 * @author Jeff Kesselman
 */
public abstract class InOrderTreeNode implements Serializable, ManagedObject,
    Task
{
    public static final long SerialVersionUID = 1L;
    ManagedReference parentRef;
    
    public InOrderTreeNode(InOrderTreeNode parent){
        if (parent != null ){
            parentRef = AppContext.getDataManager().createReference(parent);
        }
        
    }
    
    public void evaluate(){
        preDescentEvaluation();
        doNextChild(null);
    }
    
    private void doNextChild(InOrderTreeNode lastChild) {
        InOrderTreeNode child = nextChild(lastChild);
        if (child == null) { // done with children
            postDescentEvaluation();
            if (!isRoot()){
                parentRef.get(InOrderTreeNode.class).doNextChild(this);
            }
        } else {
            AppContext.getTaskManager().scheduleTask(child);
        }
    }
    
    public boolean isRoot(){
        return parentRef == null;
    }
    
    public void run(){
        evaluate();
    }

    protected abstract void preDescentEvaluation();

    protected abstract InOrderTreeNode nextChild(Object object);

    protected abstract void postDescentEvaluation(); 
    
    
    
}
